item11-在operator=中处理自我赋值
item11-在operator=中处理自我赋值
现实中,存在潜在的自我赋值:
a[i] = a[j]; //i == j时,自我赋值
*px = *py; //px == py是,自我赋值
自定义类型常见的赋值操作符实现:
Widget& operator=(const Widget& rhs) {
delete ptr;
ptr = new A(*rhs.ptr);
return *this;
}
这种写法有两种风险:
- (*this).ptr 有可能等于rhs.ptr,这样的话,delete ptr时,双方的内容都被释放
- 如果new时发生异常,但此时(*this).ptr已经被delete
优化:
Widget& operator=(const Widget& rhs) {
if(this == &rhs)return *this; //证同测试
A* tmp = ptr;
ptr = new A(*rhs.ptr);
delete tmp; //new 成功后再释放
return *this;
}
进阶,使用copy and swap技术:
// 写法1,函数参数为引用
Widget& operator=(const Widget& rhs) {
Widget tmp(rhs);
swap(tmp);
return *this;
}
// 写法2,函数参数为值传递,值传递的参数本身就是一份副本
Widget& operator=(Widget rhs) {
swap(rhs);
return *this;
}